home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_052 / assign / assign.c < prev   
C/C++ Source or Header  |  1992-05-06  |  11KB  |  310 lines

  1. /* 
  2.  * Assign Command - C Language Equivalent. 
  3.  *
  4.  *     This command looks and feels like the original AmigaDOS Assign command
  5.  *  except that it is written in C and thus available for "forking." Also 
  6.  *  since it is written in C it is a somewhat larger than it's BCPL counterpart
  7.  *  although a good assembly hack could probably fix that. 
  8.  *
  9.  *  (c) Copyright 1986 Charles McManis, All rights reserved.
  10.  *  This code may be copied for private use only. It may not be
  11.  *  included as part of any commercial package in whole or in
  12.  *  part without the express written permission of the Author.
  13.  *  
  14.  */
  15.  
  16. #include <exec/types.h>
  17. #include <libraries/dos.h>
  18. #include <libraries/dosextens.h>
  19. #include <libraries/filehandler.h>
  20. #include <stdio.h>
  21.  
  22. extern struct DosLibrary *DOSBase;
  23.  
  24. #define PATHSIZE        128     /* This is max numbers in a path (Arbitrary) */
  25. struct DosInfo          *di; 
  26. struct FileInfoBlock    *fi;    /* Our file info (on directory assigns) */
  27. char                    *pathstr, *tmpstr;
  28.  
  29. /* 
  30.  * Function - MyExit(ConditionCode)
  31.  *   This is the final exit routine, if we can't find something we need 
  32.  * like memory we go here and free up what we have. Exit code is 'cc'.
  33.  */
  34. void MyExit(cc)
  35.  
  36. int     cc;
  37.  
  38. {
  39.   if (fi != NULL)      FreeMem(fi,sizeof(struct FileInfoBlock));
  40.   if (pathstr != NULL) FreeMem(pathstr,PATHSIZE);
  41.   if (tmpstr != NULL)  FreeMem(tmpstr,PATHSIZE);
  42.   exit(cc);
  43. }
  44.  
  45. /*
  46.  * Function - CvtBstr(str)
  47.  *    This function takes a BPTR to a BSTR and returns a pointer to an 
  48.  * equivalent C string that may be printed or copied.
  49.  */
  50.  
  51. #define STRSIZE 81
  52.  
  53. char *
  54. CvtBstr(bstr)
  55.  
  56. char    *bstr;
  57.  
  58. {
  59.   int   i,mx;
  60.   char  *foo;
  61.   static char   tmpstr[STRSIZE]; /* Maximum size */
  62.   
  63.   foo = (char *)(BADDR(bstr));
  64.   mx = (foo[0] < STRSIZE) ? foo[0] : STRSIZE; /* Safety net */
  65.   for (i=0; i<mx; i++) tmpstr[i] = foo[i+1];
  66.   tmpstr[i] = '\0';
  67.   return(tmpstr);
  68. }
  69.  
  70. /* 
  71.  * Function - DeleteDevice(Name)
  72.  *     This function will search the device list for a directory entry
  73.  * matching the one passed, and remove it from the device list.
  74.  *
  75.  * Returns 0 if successful.
  76.  */
  77.  
  78. int
  79. DeleteDevice(nm)
  80.  
  81. char    *nm;            /* String pointer to the Name */
  82.  
  83. {
  84.   struct DeviceList     *prevdev,*thisdev;
  85.   char                  *str;
  86.   int                   i,found;
  87.  
  88.   prevdev = NULL;
  89.   thisdev = (struct DeviceList *)BADDR(di->di_DevInfo);
  90.   found = -1;
  91.   while (thisdev != NULL) {
  92.     if (thisdev->dl_Type == DLT_DIRECTORY) {
  93.       str = CvtBstr(thisdev->dl_Name);
  94.       if (stricmp(str,nm) == 0) {
  95.         found = 0;
  96.         if (prevdev == NULL) {                  /* If first device      */
  97.           Forbid();                             /* Turn off tasking     */
  98.           di->di_DevInfo = thisdev->dl_Next;    /* Delete from list     */
  99.           Permit();                             /* Turn tasking back on */
  100.         }
  101.         else { 
  102.           Forbid();                             /* Turn off tasking     */
  103.           prevdev->dl_Next = thisdev->dl_Next;  /* Delete from list     */
  104.           Permit();                             /* Back to multitasking */
  105.         }
  106.         /* Now free the Lock, the String, and the DevList structure     */
  107.         UnLock(thisdev->dl_Lock);                /* free the lock       */
  108.         str = (char *)(BADDR(thisdev->dl_Name)); /* easier to read      */
  109.         i = str[0];
  110.         FreeMem(str,i);                         /* Free the string      */
  111.         FreeMem(thisdev,sizeof(struct DeviceList)); /* Free struct      */
  112.         break;                                  /* Exit the while loop  */
  113.       } /* if matched devices           */
  114.     } /* if it was a directory entry    */
  115.     prevdev = thisdev;                  /* If not found, walk the list  */
  116.     thisdev = (struct DeviceList *)BADDR(thisdev->dl_Next);
  117.   } /* While */
  118.   return(found);
  119. }
  120.  
  121. /*
  122.  * Main code, options of the Assign command are name, directory, or List.
  123.  * the default is to list the current assignments, Volumes, and devices.
  124.  *
  125.  */
  126.  
  127. void main(argc,argv)
  128.  
  129. int     argc;           /* Number of arguments (max 3)  */
  130. char    *argv[];        /* Text of the arguments        */
  131.  
  132. {
  133.   /* The pointers here make it easier later */
  134.  
  135.   struct RootNode       *rn;
  136.   struct DeviceList     *dl, *curdev, *xl;
  137.   struct DeviceNode     *dn;
  138.   struct FileLock       *fl;
  139.   BPTR                  plock, thislock, tb;
  140.   char                  Name[41],Path[81],*sptr;
  141.   int                   i,listem;
  142.  
  143.   /* Get some memory for various buffers */
  144.   fi = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),0);
  145.   if (fi == NULL) MyExit(RETURN_FAIL);
  146.   pathstr = (char *)AllocMem(PATHSIZE,0);
  147.   if (pathstr == NULL) MyExit(RETURN_FAIL);
  148.   tmpstr = (char *)AllocMem(PATHSIZE,0);
  149.   if (tmpstr == NULL) MyExit(RETURN_FAIL);
  150.  
  151.   printf("Assign command substitute v1.0\n");
  152.   /* Then we track down the head of the Device list from the Root Node */
  153.   rn = (struct RootNode *)DOSBase->dl_Root;
  154.   di = (struct DosInfo *)BADDR(rn->rn_Info);
  155.   /* dl becomes the anchor point that we always start from */
  156.   dl = (struct DeviceList *)BADDR(di->di_DevInfo);  
  157.   listem = FALSE; /* Initially no list output   */
  158.   Name[0] = '\0'; /* No name parameter          */
  159.   Path[0] = '\0'; /* And no path specifier      */
  160.  
  161. /*************************************************************************
  162.  * Process the arguments passed. To be 100% compatible with the AmigaDOS *
  163.  * assign command.                                                       *
  164.  *************************************************************************/
  165.  
  166.   if (argc > 4) {
  167.     printf("Too many arguments, usage is Assign [Name:] [Dir:] [List]\n"); 
  168.     MyExit(RETURN_WARN);
  169.   }
  170.   for (i=1; i<argc; i++) 
  171.     if (stricmp(argv[i],"LIST") == 0) listem = TRUE;
  172.     else if (Name[0] == '\0') strcpy(Name,argv[i]);
  173.     else if (Path[0] == '\0') strcpy(Path,argv[i]);
  174.     else {
  175.       printf("Bad Arguments, usage is Assign [Name:] [Dir:] [List]\n");
  176.       MyExit(RETURN_WARN);
  177.     }
  178.   if (strcmp(Name,"?") == 0) {
  179.     printf("Usage is Assign [Name:] [Dir:] [List]\n");
  180.     MyExit(RETURN_OK);
  181.   }
  182.   if (argc > 1) {
  183.     if ((sptr = (char *)strchr(Name,':')) == NULL) {
  184.       printf("Improper device name format.\n");
  185.       MyExit(RETURN_WARN);
  186.     }
  187.     *sptr = '\0'; /* Eliminate the trailing colon */
  188.   }
  189.   /* Ok, now we have the parameters they work like this, if a name was 
  190.    * supplied but no path then it is a deassign operation, if both are
  191.    * supplied it is an assign operation, if both are missing it is a 
  192.    * list operation 
  193.    */
  194.   if ((Name[0] != '\0') && (Path[0] == '\0')) /* DEASSIGN 'Name' */
  195.     if (DeleteDevice(Name) != 0) {
  196.       printf("Device %s: Not found.\n");        
  197.       MyExit(RETURN_WARN);
  198.     }
  199.   if ((Name[0] != '\0') && (Path[0] != '\0')) { /* ASSIGN 'Name' */
  200.     (void) DeleteDevice(Name);          /* Delete in case it exists        */
  201.     if ((thislock = Lock(Path,ACCESS_READ)) != 0) {
  202.       dl = (struct DeviceList *)AllocMem(sizeof(struct DeviceList),0);
  203.       sptr = (char *)AllocMem(strlen(Name)+1,0); 
  204.       strcpy(sptr+1,Name); /* Create BSTR out of Name */
  205.       *sptr = strlen(Name);
  206.       dl->dl_Name = (BSTR *)(((long)sptr) >> 2); /* Convert to BSTR ptr    */
  207.       dl->dl_Lock = thislock;           /* Put the BPTR value into Lock    */
  208.       dl->dl_Type = DLT_DIRECTORY;      /* The type is Directory           */
  209.       fl = (struct FileLock *)(BADDR(thislock)); /* for convience          */
  210.       dl->dl_Task = fl->fl_Task;        /* Copy the message port task ptr  */
  211.       tb = (BPTR)(((long)dl) >> 2);     /* Make a BPTR out of our pointer  */
  212.       Forbid();                         /* Disable multitasking            */
  213.       dl->dl_Next = di->di_DevInfo;     /* Insert it at the head           */
  214.       di->di_DevInfo = tb;              /* Put a pointer to us in DevInfo  */
  215.       Permit();                         /* Start up Multitasking again     */
  216.     } /* if we got the lock */
  217.     else {
  218.       printf("Couldn't get a Lock on %s\n",Path);
  219.       MyExit(RETURN_WARN);
  220.     }
  221.   } /* ASSIGN operation */
  222.   if (((Name[0] != '\0') || (Path[0] != '\0')) && ! listem) MyExit(RETURN_OK);
  223.  
  224.   /* The remainder of the code lists out the current assignments, if
  225.    * no arguments, or the argument "List" is included it will run this
  226.    * section.
  227.    *
  228.    * Pass 1: Print out all of the known volumes, if they have a handler
  229.    *         task present then they are mounted in a physical device
  230.    */
  231.   curdev = dl;
  232.   printf("Volumes:\n");
  233.   while (curdev != NULL) {
  234.     if (curdev->dl_Type == DLT_VOLUME) {
  235.       printf("%s ",CvtBstr(curdev->dl_Name));
  236.       if (curdev->dl_Task != NULL) printf("[Mounted]");
  237.       printf("\n");
  238.     }
  239.     curdev = (struct DeviceList *)BADDR(curdev -> dl_Next);
  240.   }
  241.   printf("\n");
  242.  
  243.   /* Pass 2 : Scan for directory redirections. If the volume that the 
  244.    *          directory is redirected to is not mounted then we just
  245.    *          print out the volume name. If it is mounted we print 
  246.    *          out the full path. If we have been redirected to a device
  247.    *          like 'RAM' then we just print the device name.
  248.    */
  249.   curdev = dl;
  250.   printf("Directories:\n");
  251.   while (curdev != NULL) {
  252.     if (curdev->dl_Type == DLT_DIRECTORY) {
  253.       strcpy(tmpstr,CvtBstr(curdev->dl_Name));
  254.       printf("%s        ",tmpstr);
  255.       if (strlen(tmpstr) < 8) printf("  ");
  256.       fl = (struct FileLock *)(BADDR(curdev->dl_Lock));
  257.       xl = (struct DeviceList *)(BADDR(fl->fl_Volume));
  258.       if (xl->dl_Type == DLT_DEVICE) {
  259.         dn = (struct DeviceNode *) xl;
  260.         printf("%s:",CvtBstr(dn->dn_Name));
  261.       }
  262.       else {
  263.         if (xl->dl_Task == NULL) /* Not Mounted if Task == NULL */
  264.           printf("Volume: %s",CvtBstr(xl->dl_Name));
  265.         else { /* This code tracks down the full path */
  266.           printf("%s:",CvtBstr(xl->dl_Name));
  267.           pathstr[0] = '\0';  /* initialize it to the null string */
  268.           thislock = curdev->dl_Lock;
  269.           plock = ParentDir(thislock);
  270.           while (plock != 0) {
  271.             if (Examine(thislock,fi)) {
  272.               if (strlen(pathstr) == 0) strcpy(pathstr,fi->fib_FileName);
  273.               else {
  274.                 strins(pathstr,"/");          /* insert directory separator */
  275.                 strins(pathstr,fi->fib_FileName); /* insert parent dir name */
  276.               }
  277.             }
  278.             else printf("\nBad Lock!\n"); /* This should never print! */
  279.             thislock = plock;
  280.             plock = ParentDir(thislock);
  281.           } /* while we haven't got to the top */
  282.           printf("%s",pathstr);
  283.         }
  284.       } /* else it was a directory rather than a device */
  285.       printf("\n");
  286.     } /* If it was a directory redirection at all */
  287.     curdev = (struct DeviceList *)BADDR(curdev -> dl_Next);
  288.   }
  289.   printf("\n");
  290.  
  291.   /* Pass 3 : Print out all of the devices, like the original we pretty much
  292.    *          assume device names are three characters long. (They can be more 
  293.    *          though.)
  294.    */
  295.   printf("Devices:");
  296.   i = 0;
  297.   curdev = dl;
  298.   while (curdev != NULL) {
  299.     if (curdev->dl_Type == DLT_DEVICE) {
  300.       if ((i%5) == 0) printf("\n"); /* Every 5 devices print a newline */
  301.       i++;
  302.       dn = (struct DeviceNode *) curdev;
  303.       printf("%s  ",CvtBstr(dn->dn_Name));
  304.     }
  305.     curdev = (struct DeviceList *)BADDR(curdev -> dl_Next);
  306.   } /* While */
  307.   printf("\n");
  308.   MyExit(RETURN_OK); /* Exit with a status of zero */
  309. }
  310.